package com.kamistoat.meimeimall.meimeimallpayment.listener;

import com.kamistoat.meimeimall.common.dubboInterface.CartDubboInterface;
import com.kamistoat.meimeimall.common.dubboInterface.WareDubboInterface;
import com.kamistoat.meimeimall.common.exception.BizCodeEnum;
import com.kamistoat.meimeimall.common.exception.RRException;
import com.kamistoat.meimeimall.meimeimallpayment.service.ReconciliationTaskService;
import com.rabbitmq.client.Channel;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.dubbo.config.annotation.Reference;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;


/**
 * 监听到对账任务开启消息后，开启对账任务。
 * 100W数据压测：
 * 第三方订单数据清洗：19s.
 * 关联本地流水-第三方订单：1m36s.
 * 对账：2m8s
 */
@Service
public class ReconciliationTaskStartListener {
    protected Logger logger = LoggerFactory.getLogger(ReconciliationTaskStartListener.class);

    @Autowired
    ReconciliationTaskService reconciliationTaskService;

    /**
     * 监听到对账任务开启
     *
     * @param message 消息
     * @param taskId  任务Id
     * @param channel
     */
    @RabbitListener(queues = "reconciliation.task.start.queue")
    public void createUnpayListener(Message message, Long taskId, Channel channel) throws IOException {
        logger.info("检测到对账任务" + taskId + "的启动动作:");
        // 消息序号，用于全部成功后手动向MQ进行ACK确认
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            // 对账无异常，直接ack
            reconciliationTaskService.reconciliationTaskExecute(taskId);
            channel.basicAck(deliveryTag, false);
        } catch (Exception exception) {
            // 如果对账已经完成，只是更新任务状态出错，则依然ack
            if(exception instanceof RRException && ((RRException) exception).getCode() == BizCodeEnum.RECONCILIATION_FINISH_BUT_UPDATE_ERROR.getCode()) {
                channel.basicAck(deliveryTag, false);
            }else{
                // 否则reject重试
                channel.basicReject(deliveryTag, true);
            }
            throw exception;
        }
    }
}
